package com.luych.toolbox.data.service.controller;

import com.luych.toolbox.common.constant.PageConstant;
import com.luych.toolbox.common.enums.CaseType;
import com.luych.toolbox.common.enums.DataSourceType;
import com.luych.toolbox.common.feign.intf.database.service.DataSourceFeign;
import com.luych.toolbox.common.feign.param.UserAndPassParam;
import com.luych.toolbox.common.feign.param.data.service.DataSourceParam;
import com.luych.toolbox.common.feign.view.data.service.*;
import com.luych.toolbox.common.page.CommonPageParam;
import com.luych.toolbox.common.page.CommonPageResult;
import com.luych.toolbox.common.page.CommonSort;
import com.luych.toolbox.common.page.PageResult;
import com.luych.toolbox.common.service.base.BaseController;
import com.luych.toolbox.data.service.core.CoreBuilder;
import com.luych.toolbox.data.service.entity.DataSource;
import com.luych.toolbox.data.service.service.DataSourceService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Api(tags = "数据源")
@RestController
@RequestMapping("/ds")
public class DataSourceController
        extends BaseController<DataSourceView, DataSourceParam, DataSource>
        implements DataSourceFeign {

    private final DataSourceService dataSourceService;

    @Autowired
    public DataSourceController(DataSourceService dataSourceService) {
        super(dataSourceService);
        this.dataSourceService = dataSourceService;
    }

    @ApiOperation("按关键字查询数据源信息")
    @GetMapping("/search/keyword")
    public CommonPageResult<DataSourceView> pageByKeyword(
            @ApiParam(value = "每页容量") @RequestHeader(name = "pageSize", required = false, defaultValue = PageConstant.DEFAULT_PAGE_SIZE_STR) long pageSize,
            @ApiParam(value = "查询页码") @RequestHeader(name = "pageNumber", required = false, defaultValue = PageConstant.DEFAULT_PAGE_NUMBER_STR) long pageNumber,
            @ApiParam(value = "排序字段") @RequestHeader(name = "sort", required = false, defaultValue = PageConstant.DEFAULT_PAGE_SORT) String sort,
            @ApiParam(value = "正序/倒序，取值ASC/DESC") @RequestHeader(name = "order", required = false, defaultValue = PageConstant.DEFAULT_PAGE_ORDER) String order,
            @ApiParam(value = "查询关键字，支持按名称和连接地址模糊查询") @RequestParam(name = "keyword", required = false) String keyword
    ) {
        CommonPageParam commonPageParam = CommonPageParam.getInstance().setPageSize(pageSize).setPageNumber(pageNumber);
        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(order)) {
            commonPageParam.addSort(CommonSort.getInstance().setSort(sort).setOrder(order));
        }
        PageResult<DataSourceView> pageResult = dataSourceService.pageByKeyword(commonPageParam, keyword);
        return CommonPageResult.getInstance(pageResult);
    }

    @ApiOperation("查询数据源类型")
    @GetMapping("/type")
    public CommonPageResult<DataSourceTypeView> listDataSourceType() {
        List<DataSourceTypeView> dataSourceTypeViews = new ArrayList<>();
        for (DataSourceType dataSourceType : DataSourceType.values()) {
            DataSourceTypeView dataSourceTypeView = new DataSourceTypeView();
            dataSourceTypeView.setValue(dataSourceType.getValue());
            dataSourceTypeView.setName(dataSourceType.name());
            dataSourceTypeViews.add(dataSourceTypeView);
        }
        CommonPageResult<DataSourceTypeView> commonPageResult = new CommonPageResult<>();
        commonPageResult.setTotal(dataSourceTypeViews.size());
        commonPageResult.setRecords(dataSourceTypeViews);
        return commonPageResult;
    }

    @ApiOperation("查询字段类型")
    @GetMapping("/type/{type}/type")
    public CommonPageResult<DataSourceDataTypeView> listDataColumnType(@ApiParam(value = "数据源类型") @PathVariable String type) {
        DataSourceType dataSourceType = null;
        try {
            dataSourceType = DataSourceType.valueOf(type);
        } catch (IllegalArgumentException e) {
            return new CommonPageResult<>(new ArrayList<>(), 0);
        }
        List<String> columnTypes = CoreBuilder.listDataTypes(dataSourceType);
        CommonPageResult<DataSourceDataTypeView> commonPageResult = new CommonPageResult<>();
        commonPageResult.setTotal(columnTypes.size());
        commonPageResult.setRecords(columnTypes.stream().map(name -> new DataSourceDataTypeView(name, name)).collect(Collectors.toList()));
        return commonPageResult;
    }

    @ApiOperation("时间线")
    @GetMapping("/{id}/timeline")
    public List<DataSourceTimeLineView> timelines(@ApiParam(value = "ID") @PathVariable String id) {
        return dataSourceService.timelines(id);
    }

    @ApiOperation("查询大小写转换类型")
    @GetMapping("/case")
    public CommonPageResult<CaseTypeView> listCaseType() {
        List<CaseTypeView> caseTypeViews = new ArrayList<>();
        for (CaseType caseType : CaseType.values()) {
            CaseTypeView caseTypeView = new CaseTypeView();
            caseTypeView.setValue(caseType.getValue());
            caseTypeView.setName(caseType.name());
            caseTypeViews.add(caseTypeView);
        }
        CommonPageResult<CaseTypeView> commonPageResult = new CommonPageResult<>();
        commonPageResult.setTotal(caseTypeViews.size());
        commonPageResult.setRecords(caseTypeViews);
        return commonPageResult;
    }

    @ApiOperation("克隆为新数据源")
    @PatchMapping("/{id}/clone")
    public DataSourceView clone(@ApiParam(value = "ID") @PathVariable String id,
                                @ApiParam(value = "名称") @RequestBody String name) {
        return dataSourceService.clone(id, name);
    }

    @ApiOperation("补充超级用户")
    @PatchMapping("/{id}/super")
    public void setSuper(@ApiParam(value = "ID") @PathVariable String id,
                         @ApiParam(value = "超级用户信息") @RequestBody UserAndPassParam param) {
        dataSourceService.setSuper(id, param);
    }

    @ApiOperation("执行SQL查询")
    @PatchMapping("/{id}/query")
    public List<Map<String, Object>> query(@ApiParam(value = "ID") @PathVariable String id,
                                           @ApiParam(value = "SQL") @RequestBody String sql) {
        return dataSourceService.query(id, sql);
    }

    @ApiOperation("执行SQL更新")
    @PatchMapping("/{id}/execute")
    public void execute(@ApiParam(value = "ID") @PathVariable String id,
                        @ApiParam(value = "SQL") @RequestBody String sql) {
        dataSourceService.execute(id, sql);
    }

    @ApiOperation("获取更多信息")
    @GetMapping("/{id}/more")
    public DataSourceMoreView more(@ApiParam(value = "ID") @PathVariable String id) {
        return dataSourceService.more(id);
    }

    @Override
    public String password(String id) {
        return dataSourceService.password(id);
    }

    @ApiOperation("获取表创建SQL")
    @GetMapping("/{id}/table/{name}/sql/create")
    public String getTableCreateSql(@ApiParam(value = "ID") @PathVariable String id,
                                    @ApiParam(value = "表") @PathVariable String name,
                                    @ApiParam(value = "目标数据源类型") @RequestParam(required = false) DataSourceType dst,
                                    @ApiParam(value = "大小写转换方式") @RequestParam(required = false) CaseType ct) {
        return dataSourceService.getTableCreateSql(id, name, dst, ct);
    }

    @ApiOperation("获取表删除SQL")
    @GetMapping("/{id}/table/{name}/sql/remove")
    public String getTableRemoveSql(@ApiParam(value = "ID") @PathVariable String id,
                                    @ApiParam(value = "表") @PathVariable String name,
                                    @ApiParam(value = "目标数据源类型") @RequestParam(required = false) DataSourceType dst,
                                    @ApiParam(value = "大小写转换方式") @RequestParam(required = false) CaseType ct) {
        return dataSourceService.getTableRemoveSql(id, name, dst, ct);
    }

    @ApiOperation("获取字段创建SQL")
    @GetMapping("/{id}/table/{tn}/column/{cn}/sql/create")
    public String getColumnCreateSql(@ApiParam(value = "ID") @PathVariable String id,
                                     @ApiParam(value = "表") @PathVariable String tn,
                                     @ApiParam(value = "字段") @PathVariable String cn,
                                     @ApiParam(value = "目标数据源类型") @RequestParam(required = false) DataSourceType dst,
                                     @ApiParam(value = "大小写转换方式") @RequestParam(required = false) CaseType ct) {
        return dataSourceService.getColumnCreateSql(id, tn, cn, dst, ct);
    }

    @ApiOperation("获取字段修改SQL")
    @GetMapping("/{id}/table/{tn}/column/{cn}/sql/modify")
    public String getColumnModifySql(@ApiParam(value = "ID") @PathVariable String id,
                                     @ApiParam(value = "表") @PathVariable String tn,
                                     @ApiParam(value = "字段") @PathVariable String cn,
                                     @ApiParam(value = "目标数据源类型") @RequestParam(required = false) DataSourceType dst,
                                     @ApiParam(value = "大小写转换方式") @RequestParam(required = false) CaseType ct) {
        return dataSourceService.getColumnModifySql(id, tn, cn, dst, ct);
    }

    @ApiOperation("获取字段删除SQL")
    @GetMapping("/{id}/table/{tn}/column/{cn}/sql/remove")
    public String getColumnRemoveSql(@ApiParam(value = "ID") @PathVariable String id,
                                     @ApiParam(value = "表") @PathVariable String tn,
                                     @ApiParam(value = "字段") @PathVariable String cn,
                                     @ApiParam(value = "目标数据源类型") @RequestParam(required = false) DataSourceType dst,
                                     @ApiParam(value = "大小写转换方式") @RequestParam(required = false) CaseType ct) {
        return dataSourceService.getColumnRemoveSql(id, tn, cn, dst, ct);
    }
}
